from pysplit import generate_bulktraj
from datetime import datetime
import os
import pandas as pd
import json
import sqlite3
import requests
import pandas as pd
import numpy as np
from tqdm import tqdm
from datetime import datetime
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
with open('/root/Programs/NovaPrograms/set/_ads.json', 'r', encoding='utf-8') as file:  
    VALUE_SETS = json.load(file)

# 设置后向模拟参数
working_dir = VALUE_SETS["TRA_PATH"]["WORKDIR"]  # 指定工作目录
meteo_dir = VALUE_SETS["TRA_PATH"]["METODIR"]  # 指定气象数据目录
hys_std_dir = VALUE_SETS["TRA_PATH"]["HTSPLIT_STD"]
store_dir = VALUE_SETS["TRA_PATH"]["STOREDIR"]

class TarJectory:
    def __init__(self):
        #生成后向轨迹所需要的文件路径
        self.working_dir = working_dir
        self.meteo_dir = meteo_dir
        self.store_dir = store_dir
        self.hys_std_dir = hys_std_dir
        #create session
        self.s = requests.Session()
        #configuration database
        self.conn = sqlite3.connect(VALUE_SETS["DB_NAME"])
        self.cursor = self.conn.cursor()
        self.cursor.execute("""
            CREATE TABLE IF NOT EXISTS TraJ_Table (  
                data TEXT, 
                year INT,  
                month INT,  
                day INT,  
                hour INT,  
                minite INT,
                second INT,  
                longitude FLOAT,          
                latitude FLOAT,  
                height FLOAT,
                press FLOAT,       
                PRIMARY KEY (data)  
            );
        """)
        
    #生成后向轨迹
    def _gen_back_traj(self,motion:dict) -> None:
        """
        extract datas from trajectory file.

        Parameters
        ----------
        motion : dict
            The dict of param

        Such as:
        -------
        motion = {
            'year_range':[2023],
            'month_range':[10,11],
            'hour_range':[6, 15, 18, 21], 
            'height':[1000], 
            'site':(40.0, -90.0),
            'coordinates':-96
        }

        Returns:
        -------
            None

        """
        generate_bulktraj('umn', self.working_dir,
                          self.meteo_dir, self.store_dir,motion['year_range'],
                          motion['month_range'], 
                          motion['hour_range'], motion['height'], motion['site'],motion['coordinates'],
                        get_clipped=False,hysplit=self.hys_std_dir)

    #获取文件名列表
    def get_all_files_in_directory(self,directory:str=VALUE_SETS["TRA_PATH"]["METODIR"]) -> tuple:  
        """
        extract datas from trajectory file.

        Parameters
        ----------
        directory : string
            The name of a trajectory file directory path

        Returns tuple

        """
        directory = '/root/Programs/NovaPrograms/datas/_par_gdas'
        file_list = []  
        for root, dirs, files in os.walk(directory):  
            for file in files:  
                file_list.append(os.path.join(root, file))  
        return file_list

    #关键信息提取，返回元组
    def parse_single_file(self,file_path:str) -> tuple:
        """
        extract datas from trajectory file.

        Parameters
        ----------
        file_path : string
            The name of a trajectory file

        Returns tuple
        -------
        year,month,day,hour,second,log,lati,height,pres
        """
        try:
            # 读取文件  
            with open(file_path, 'r') as file:  
                content = file.read()

            # 解析文件内容  
            data = content.split('\n')
            _no = 0
            # 提取试验数据  
            experiment_data = []  
            for line in data:  
                if 'GDAS' in line and _no==1:  
                    values = line.split()  
                    
                    experiment_data.append({  
                        'DataSrc': str(values[0]), 
                        'lable': 'begin time' ,
                        'year': values[1],  
                        'month': values[2],  
                        'day': values[3],  
                        'hour': values[4],
                        'minite':values[5],
                        'second': 0
                    })
                if 'GDAS' in line and _no==2:  
                    values = line.split()  
                    experiment_data.append({  
                        'DataSrc': str(values[0]), 
                        'lable' : 'end time' ,
                        'year': values[1],  
                        'month': values[2],  
                        'day': values[3],  
                        'hour': values[4],
                        'minite':values[5],
                        'second': 0
                    })
                if(_no >= 7):
                    values = line.split() 
                    print(values)
                    _year:int = int(values[2])+2000
                    print(_year)
                    time_obj = datetime(_year,int(values[3]) , int(values[4]),int(values[5]))
                    experiment_data.append({  
                        'time': time_obj,
                        'year': values[2],  
                        'month': values[3],  
                        'day': values[4],  
                        'hour': values[5],
                        'minite':values[6],
                        'second': values[7],
                        'latitude':values[9],
                        'longitude':values[10],
                        'height':values[11],
                        'pres':values[12]
                    })
                _no += 1
        except:
            print(f'parse {file} fail')
        
        return experiment_data

    #批量解析文件存入数据库
    def parse_multi_file(self) -> None:
        """
        parse all trajctory datas from trajectory file.

        Returns:
        -------
            None

        """
        file_list:tuple = self.get_all_files_in_directory()
        #print(file_list,'\n')
                    #拼接sql语句，准备插入数据库
        sql_statement = "INSERT OR UPDATE INTO TraJ_Table(data,year,month,day,hour,minite,second,longitude,latitude,height,press) VALUES(?,?,?,?,?,?,?,?,?,?,?)"
        sql_statement2 = "INSERT INTO TraJ_Table(data,year,month,day,hour,minite,second,longitude,latitude,height,press) VALUES(?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(data) "\
        "DO UPDATE SET year=?, month=?, day=?, hour=?, minite=?, second=?, longitude=?, latitude=?, height=?, press=?"
       
        _id = 0
        for file in file_list:
            #print(file,'\n')
            file_tuple:tuple=self.parse_single_file(file)
            _no = 0 
            if len(file_tuple) <= 2:
                continue
            for item in list(file_tuple): 
                if  _no < 2:
                    _no += 1
                    continue
                #date_time = item['year']*1000 + item['month']*100 + item['hour']*10 + item['minite']
                data = []
                data.extend([
                    str(item['time']),
                    item['year'],
                    item['month'],
                    item['day'],
                    item['hour'],
                    item['minite'],
                    item['second'],
                    item['longitude'],
                    item['latitude'],
                    item['height'],
                    item['pres']
                ])
                _id += 1
                try:
                #执行插入操作，向数据库中插入数据
                    self.cursor.execute(sql_statement2,data)
                    self.conn.commit()
                except:
                    print('insert sqlite fail!!!')

            _no += 1 

    def _cluster_(self) -> None:
        # 执行SELECT查询并获取结果
        self.cursor.execute('SELECT latitude FROM Traj_Table ORDER BY data ASC')
        result1 = self.cursor.fetchall()
        # 将结果存储在列表中
        latitude = [row[0] for row in result1]

        self.cursor.execute('SELECT longitude FROM Traj_Table ORDER BY data ASC')
        result2 = self.cursor.fetchall()
        # 将结果存储在列表中
        longitude = [row[0] for row in result2]

        self.cursor.execute('SELECT height FROM Traj_Table ORDER BY data ASC')
        result3 = self.cursor.fetchall()
        # 将结果存储在列表中
        height = [row[0] for row in result3]


        # 创建一个空的二维数组
        data = [[0, 0] for _ in range(len(longitude))]

        # 将arr1和arr2的元素分别放入二维数组的每一行中
        for i in range(len(longitude)):
            data[i][0] = longitude[i]
            data[i][1] = latitude[i]
        print(data)

        # 创建KMeans对象并指定聚类数量
        kmeans = KMeans(n_clusters=2)
        
        # 执行聚类
        kmeans.fit(data)

        # 获取聚类结果
        labels = kmeans.labels_
        centroids = kmeans.cluster_centers_

        # 绘制聚类结果
        colors = ["g.", "r."]
        for i in range(len(data)):
            plt.plot(data[i][0], data[i][1], colors[labels[i]], markersize=10)

        # 绘制聚类中心点
        plt.scatter(centroids[:, 0], centroids[:, 1], marker="x", s=150, linewidths=5, zorder=10)

        plt.savefig("/root/Programs/NovaPrograms/datas/photo/test.pdf")

tar_obj = TarJectory()
tar_obj._cluster_()